from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from role.models import Role
from menu.models import Menu
from role.models import RoleMenu
from frame_server.serializers import BaseSerializer as BSerializer

class AddEditBase(BSerializer):
    roleName = serializers.CharField(max_length=50, error_messages={"required":'请输入角色名',"max_length":"角色名超出最大长度"})
    roleAlias = serializers.CharField(
        required=False,
        max_length=50,
        validators=[UniqueValidator(queryset=Role.objects.all(), message="角色别名已存在")],
        error_messages={"max_length":'角色别名超出最大长度'}
    )
    sort = serializers.IntegerField(error_messages={"required":'请输入排序'})
    parentId = serializers.IntegerField(required=False, allow_null=True)

    class Meta:
        model = Role

    def validate_parentId(self, val):
        if not val:
            return None
        if not Role.objects.filter(id=val).exists():
            raise serializers.ValidationError("上级角色不存在")
        return Role.objects.only('id').get(id=val)

# 新增角色
class AddValidate(AddEditBase):
    class Meta(AddEditBase.Meta):
        exclude = ['id']

# 修改角色
class EditValidate(AddEditBase):
    id = serializers.IntegerField(error_messages={"required":'id不能为空'})
    
    def validate_id(self, val):
        if not Role.objects.filter(id=val).exists():
            raise serializers.ValidationError("编辑对象不存在")
        return val

    class Meta(AddEditBase.Meta):
        fields = '__all__'

    
# 给角色分配菜单验证
class GrantValidate(serializers.Serializer):
    roleId = serializers.IntegerField(error_messages={"required":'角色id不能为空'})
    menuIds = serializers.ListField()

    def validate(self, data):
        roleId = data['roleId']
        menuIds = data.get('menuIds',[])
        if not Role.objects.filter(id=roleId).exists():
            raise serializers.ValidationError("角色不存在")
        if Menu.objects.filter(id__in=[int(i) for i in menuIds]).count() != len(menuIds):
            raise serializers.ValidationError('部分菜单不存在')
        return data
    
    def create(self, data):
        roleId = data['roleId']
        RoleMenu.objects.filter(role_id=roleId).delete()
        role_menus = [RoleMenu(role_id=roleId, menu_id=int(id)) for id in data['menuIds']]
        for i in RoleMenu.objects.bulk_create(role_menus):
            i.save() # 为了触发信号
        return True
    